import { type Node } from '@xyflow/react';
import { z } from 'zod';

/**
 * @enum NodeType
 * @description 定义行为树节点的类型。
 */
export const enum NodeType {
    Sequence = 'sequence',
    Selector = 'selector',
    Action = 'action',
    Condition = 'condition',
    Decorator = 'decorator',
}

/**
 * @interface BaseNodeData
 * @description 定义行为树节点的基础数据接口。
 * @property {string} label - 节点的显示名称。
 */
export const BaseNodeDataSchema = z.object({
    label: z.string().min(1, '标签不能为空'),
});

export type BaseNodeData = z.infer<typeof BaseNodeDataSchema>;

// Sequence 和 Selector 节点通常只有 label
export const SequenceNodeDataSchema = BaseNodeDataSchema.extend({});

export const SelectorNodeDataSchema = BaseNodeDataSchema.extend({});

// Action 节点可能包含一个动作名称或执行路径
export const ActionNodeDataSchema = BaseNodeDataSchema.extend({
    actionName: z.string().min(1, '动作名称不能为空').optional().or(z.literal('')),
}).catchall(z.unknown());

// Condition 节点可能包含一个条件表达式或判断逻辑
export const ConditionNodeDataSchema = BaseNodeDataSchema.extend({
    condition: z.string().min(1, '条件不能为空').optional().or(z.literal('')),
}).catchall(z.unknown());

// Decorator 节点可能包含一个修饰器参数，例如重复次数
export const DecoratorNodeDataSchema = BaseNodeDataSchema.extend({
    times: z.number().int().min(1, '重复次数必须是正整数').optional().or(z.literal('')), // Empty string for empty number input
}).catchall(z.unknown());

/**
 * @type NodeData
 * @description 定义行为树节点的数据类型，它是所有具体节点数据 schema 的联合类型。
 */
export type NodeData = z.infer<
    | typeof SequenceNodeDataSchema
    | typeof SelectorNodeDataSchema
    | typeof ActionNodeDataSchema
    | typeof ConditionNodeDataSchema
    | typeof DecoratorNodeDataSchema
> & {
    // 允许 NodeData 包含 NodeSchemas 中未明确定义的其他属性
    [key: string]: unknown;
};

/**
 * @interface BehaviorTreeNode
 * @description 扩展 React Flow 的 Node 接口，用于行为树的特定节点。
 * @extends {Node}
 * @property {NodeType} type - 行为树节点的具体类型。
 * @property {NodeData} data - 节点的数据，包含 label 和其他自定义属性。
 */
export interface BehaviorTreeNode extends Node<NodeData> {
    type: NodeType;
}

// 导出所有 Schema，方便在 PropertiesPanel 中根据类型查找
export const NodeSchemas = {
    [NodeType.Sequence]: SequenceNodeDataSchema,
    [NodeType.Selector]: SelectorNodeDataSchema,
    [NodeType.Action]: ActionNodeDataSchema,
    [NodeType.Condition]: ConditionNodeDataSchema,
    [NodeType.Decorator]: DecoratorNodeDataSchema,
};